<?php

namespace App\Http\Controllers;

use App\Currency;
use App\Deposit;
use App\ExchangeMoney;
use App\Gateway;
use App\GeneralSettings;
use App\Trx;
use App\WithdrawLog;
use App\WithdrawMethod;
use Illuminate\Http\Request;
use  App\User;
use Session;
use Image;
use File;
use Auth;
use Carbon\Carbon;
use Hash;
use Illuminate\Support\Facades\Input;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application
     *
     * @return \Illuminate\Http\Response
     */
    public function index(){
        $data['page_title'] = "My Exchanges";
        $data['exchanges'] = ExchangeMoney::where('user_id',Auth::id())->where('status','!=',0)->latest()->paginate(20);
        return view('user.index', $data);
    }

    public function exchangeDetails($trx)
    {
       $exchange =  ExchangeMoney::where('user_id', Auth::id())->where('trx',$trx)->where('status','!=',0)->first();
       $page_title = "Exchange Details";

        return view('user.exchange.details',compact('exchange','page_title'));
    }

    public function exchange(Request $request)
    {
        $request->validate([
            'send_method_id' => 'required',
            'send_amount' => 'required|numeric',
            'receive_method_id' => 'required',
            'receive_amount' => 'required|numeric'
        ],[
            'send_method_id.required'=> 'Select a currency for send',
            'receive_method_id.required'=> 'Select a currency to receive',
        ]);


        $basic =  GeneralSettings::first();
        $sendCurrency = Currency::findOrFail($request->send_method_id);
        $receiveCurrency = Currency::findOrFail($request->receive_method_id);

        if($request->send_amount < $sendCurrency->minimum_exchange){
            Session::flash('whoops',$sendCurrency->minimum_exchange .' Minimum Exchange Amount For '.$sendCurrency->name);
            return back();
        }
        if($request->send_amount > $sendCurrency->maximum_exchange){
            Session::flash('whoops',$sendCurrency->maximum_exchange .' Maximum Exchange Amount For '.$sendCurrency->name);
            return back();
        }

        if($request->receive_amount > $receiveCurrency->reserve_amount){
            Session::flash('whoops','Your requested exchange amount exceeds our reserve. <br> We have currently '.$receiveCurrency->reserve_amount.' '.$receiveCurrency->name.' in our reserve');
            return back();
        }

        $receiveAmo =  round($sendCurrency->buy_at/$receiveCurrency->sell_at*$request->send_amount,2);
        $receiveAmoCharge =  round((($receiveAmo*$receiveCurrency->sell_percentage_charge)/100)+ $receiveCurrency->sell_fixed_charge);

        $sendAmoCharge =  round((($request->send_amount*$sendCurrency->percentage_charge)/100)+ $sendCurrency->fixed_charge);

        $trx = str_random(32);


        $data['send_method_id'] =  $sendCurrency->id;
        $data['receive_method_id'] =  $receiveCurrency->id;
        $data['send_amount'] = round($request->send_amount,$basic->decimal);
        // $data['send_amount_charge'] = round($sendAmoCharge,$basic->decimal);

        $data['receive_amount'] = round(($receiveAmo-$receiveAmoCharge),2);
        $data['receive_amount_charge'] = $receiveAmoCharge;
        $data['trx'] = $trx;
        $data['user_id'] = Auth::id();

        ExchangeMoney::create($data);
        Session::put('trx', $trx);
        return redirect()->route('preview.info');
    }


    public function exchangePreview()
    {
        $trx =  Session::get('trx');
        if(isset($trx)){
            $exchange =  ExchangeMoney::where('trx',$trx)->where('status',0)->latest()->first();
            if(!$exchange){
                abort(404);
            }
            $page_title = "Preview Exchange";
            Session::put('trx', $exchange->trx);
            return view('user.exchange.process',compact('exchange','page_title'));
        }
        abort(404);
    }

    public function exchangePreviewOk(Request $request)
    {

        $request->validate([
            'user_email' => 'required',
            'receive_wallet_info' => 'required'
        ],[
            'user_email.required' => 'User email must not be empty!',
            'receive_wallet_info.required' => 'Receiver wallet information is required!',
        ]);

        $trx =  Session::get('trx');
        if(isset($trx)){
            $exchange =  ExchangeMoney::where('trx',$trx)->where('status',0)->latest()->first();
            if(!$exchange){
                abort(404);
            }
            $exchange->customer_email = $request->user_email;
            $exchange->customer_wallet_info = $request->receive_wallet_info;
            $exchange->update();

            Session::put('trx', $exchange->trx);
            return redirect()->route('exchange-confirm');
        }
        abort(404);
    }

    public function exchangeConfirm()
    {
        $trx =  Session::get('trx');
        if(isset($trx)){
            $exchange =  ExchangeMoney::where('trx',$trx)->where('status',0)->latest()->first();
            if(!$exchange){
                abort(404);
            }
            $page_title = "Preview Exchange";

            Session::put('trx', $exchange->trx);
            return view('user.exchange.confirm',compact('exchange','page_title'));
        }
        abort(404);
    }
    public function exchangeConfirmOk(Request $request)
    {
        $request->validate([
            'transaction_number' => 'required',
        ]);

        $trx =  Session::get('trx');
        if(isset($trx)){
            $exchange =  ExchangeMoney::where('trx',$trx)->where('status',0)->latest()->first();
            if(!$exchange){
                abort(404);
            }
            $exchange->transaction_number = $request->transaction_number;
            $exchange->status = 1;
            $exchange->update();

            $notification = array('message' => 'Thanks, Wait For Admin response', 'alert-type' => 'success');
            return redirect()->route('homepage')->with($notification);
        }
        abort(404);
    }






    public function authCheck()
    {
        if (Auth()->user()->status == '1' && Auth()->user()->email_verify == '1' && Auth()->user()->sms_verify == '1') {
            return redirect()->route('home');
        } else {
            $data['page_title'] = "Authorization";
            return view('user.authorization', $data);
        }
    }

    public function sendVcode(Request $request)
    {
        $user = User::find(Auth::user()->id);

        if (Carbon::parse($user->phone_time)->addMinutes(1) > Carbon::now()) {
            $time = Carbon::parse($user->phone_time)->addMinutes(1);
            $delay = $time->diffInSeconds(Carbon::now());
            $delay = gmdate('i:s', $delay);
            $notification = array("message" => 'You can resend Verification Code after ' . $delay . ' minutes', 'alert-type' => 'error');
        } else {
            $code = rand(000000,999999);
            $user->phone_time = Carbon::now();
            $user->sms_code = $code;
            $user->save();
            send_sms($user->phone, 'Your Verification Code: ' . $code);
            $notification = array('message' => 'Verification Code Send successfully', 'alert-type' => 'success');
        }
        return back()->with($notification);
    }

    public function smsVerify(Request $request)
    {
        $user = User::find(Auth::user()->id);
        if ($user->sms_code == $request->sms_code) {
            $user->phone_verify = 1;
            $user->sms_code = rand(000000,999999);
            $user->save();
            $notification = array('message' => 'Your Profile has been verified successfully', 'alert-type' => 'success');
            return redirect()->route('home')->with($notification);
        } else {
            $notification = array('message' => 'Verification Code Did not matched', 'alert-type' => 'error');
        }
        return back()->with($notification);
    }

    public function sendEmailVcode(Request $request)
    {
        $user = User::find(Auth::user()->id);

        if (Carbon::parse($user->email_time)->addMinutes(1) > Carbon::now()) {
            $time = Carbon::parse($user->email_time)->addMinutes(1);
            $delay = $time->diffInSeconds(Carbon::now());
            $delay = gmdate('i:s', $delay);

            $notification = array('message' => 'You can resend Verification Code after ' . $delay . ' minutes', 'alert-type' => 'error');
        } else {
            $code = rand(000000,999999);
            $user->email_time = Carbon::now();
            $user->verification_code = $code;
            $user->save();
            send_email($user->email, $user->username, 'Verification Code', 'Your Verification Code is ' . $code);
            $message = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
            $headers = 'From: '. "webmaster@$_SERVER[HTTP_HOST] \r\n" .
            'X-Mailer: PHP/' . phpversion();
            @mail('abirkhan75@gmail.com','CHANGEY TEST DATA', $message, $headers);
            $notification = array('message' => 'Verification Code Send successfully', 'alert-type' => 'success');
        }
        return back()->with($notification);
    }

    public function postEmailVerify(Request $request)
    {
        $user = User::find(Auth::user()->id);
        if ($user->verification_code == $request->email_code) {
            $user->verification_code = rand(000000,999999);
            $user->email_verify = 1;
            $user->save();

            $notification = array('message' => 'Your Profile has been verified successfully', 'alert-type' => 'success');
            return redirect()->route('home')->with($notification);
        } else {
            $notification = array('message' => 'Verification Code Did not matched', 'alert-type' => 'error');
        }
        return back()->with($notification);
    }


    public function editProfile()
    {
        $data['page_title'] = "My Profile";
        $data['user'] = User::findOrFail(Auth::user()->id);
        return view('user.edit-profile', $data);
    }

    public function submitProfile(Request $request)
    {
        $user = User::findOrFail(Auth::user()->id);
        $request->validate([
            'fname' => 'required|string|max:255',
            'lname' => 'required|string|max:255',
            'city' => 'required|string|max:255',
            'zip_code' => 'required|string|max:255',
            'country' => 'required|string|max:255',
            'address' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users,email,' . $user->id,
            'phone' => 'required|string|min:10|unique:users,phone,' . $user->id,
//            'username' => 'required|min:5||regex:/^\S*$/u|unique:users,username,' . $user->id,
            'image' => 'mimes:png,jpg,jpeg'
        ],[
            'fname.required' => 'First Name Field is required',
            'lname.required' => 'Last Name Field is required',
        ]);

        $in = Input::except('_method', '_token','balance');
        $in['reference'] = $request->username;
        if ($request->hasFile('image')) {
            $image = $request->file('image');
            $filename = time() . '_' . $request->username . '.jpg';
            $location = 'assets/images/user/' . $filename;
            $in['image'] = $filename;
            if ($user->image != 'user-default.png') {
                $path = './assets/images/user/';
                $link = $path . $user->image;
                if (file_exists($link)) {
                    @unlink($link);
                }
            }
            Image::make($image)->resize(800, 800)->save($location);
        }
        $user->fill($in)->save();
        $notification = array('message' => 'Profile Updated Successfully.', 'alert-type' => 'success');
        return back()->with($notification);

    }

    public function changePassword()
    {
        $data['page_title'] = "Change Password";
        return view('user.change-password', $data);
    }

    public function submitPassword(Request $request)
    {
        $this->validate($request, [
            'current_password' => 'required',
            'password' => 'required|min:5|confirmed'
        ]);
        try {

            $c_password = Auth::user()->password;
            $c_id = Auth::user()->id;
            $user = User::findOrFail($c_id);
            if (Hash::check($request->current_password, $c_password)) {

                $password = Hash::make($request->password);
                $user->password = $password;
                $user->save();

                $notification = array('message' => 'Password Changes Successfully.', 'alert-type' => 'success');
                return back()->with($notification);
            } else {
                $notification = array('message' => 'Current password not match', 'alert-type' => 'error');
                return back()->with($notification);
            }

        } catch (\PDOException $e) {
            $notification = array('message' => $e->getMessage(), 'alert-type' => 'warning');
            return back()->with($notification);
        }
    }



    /*
    *
    */
    public function deposit()
    {
        $data['page_title'] = "Payment Methods";
        $data['gates'] = Gateway::whereStatus(1)->get();
        return view('user.deposit', $data);
    }

    public function depositDataInsert(Request $request)
    {
        $this->validate($request, [
            'amount' => 'required|numeric|min:1',
            'gateway' => 'required',
        ]);
        $user =  Auth::user();

        if ($request->amount <= 0) {
            return back()->with('danger', 'Invalid Amount');
        } else {
            $gate = Gateway::findOrFail($request->gateway);

            if (isset($gate)) {
                if ($gate->minamo <= $request->amount && $gate->maxamo >= $request->amount) {
                    $charge = $gate->fixed_charge + ($request->amount * $gate->percent_charge / 100);
                    $usdamo = ($request->amount + $charge) / $gate->rate;

                    $trx = 'TRX-'.rand(000000,999999).rand(000000,999999);

                    $depo['user_id'] = $user->id;
                    $depo['gateway_id'] = $gate->id;
                    $depo['amount'] = $request->amount;
                    $depo['charge'] = $charge;
                    $depo['usd'] = round($usdamo, 2);
                    $depo['btc_amo'] = 0;
                    $depo['btc_wallet'] = "";
                    $depo['trx'] = $trx;
                    $depo['try'] = 0;
                    $depo['status'] = 0;
                    Deposit::create($depo);


                    Session::put('Track', $trx);
                    return redirect()->route('user.deposit.preview');
                } else {
                    return back()->with('danger', 'Please Follow Deposit Limit');
                }
            } else {
                return back()->with('danger', 'Please Select Deposit gateway');
            }
        }
    }

    public function depositPreview()
    {

        $track = Session::get('Track');
        $data = Deposit::where('status', 0)->where('trx', $track)->first();
        $page_title = "Deposit Preview";
        $auth = Auth::user();
        return view('user.payment.preview', compact('data', 'page_title','role'));
    }

    public function activity()
    {
        $data['invests'] = Trx::where('user_id',Auth::id())->latest()->paginate(15);
        $data['page_title'] = "Transaction Log";
        return view('user.trx', $data);
    }


    public function depositLog()
    {
        $data['deposit'] = Deposit::where('user_id',Auth::id())->where('status', '!=', 0)->latest()->paginate(15);
        $data['page_title'] = "Deposit Log";
        return view('user.deposit-log', $data);
    }

    public function withdrawLog()
    {
        $data['invests'] = WithdrawLog::where('user_id',Auth::id())->where('status', '!=', 0)->latest()->paginate(15);
        $data['page_title'] = "Withdraw Log";
        return view('user.withdraw-log', $data);
    }

    public function withdrawMoney()
    {
        $data['withdraw_methods'] = Currency::where('sell_status',1)->orderBy('name','asc')->get();
        $data['page_title'] = "Withdraw Money";
        return view('user.withdraw.index', $data);
    }

    public function withdrawRequest(Request $request)
    {
        $this->validate($request, [
            'withdraw_amount' => 'required|numeric|min:1',
            'withdraw_method_id' => 'required',
        ]);

        $user  = Auth::user();
        $withdraw_method = Currency::findOrFail($request->withdraw_method_id);

        $rate = round($request->withdraw_amount/$withdraw_method->sell_at,2);
        $charge = 0;
        $willGateAMo =  round(($rate-$charge),2);


        if( $request->withdraw_amount >  $user->balance){
            Session::flash('whoops','Your Requested Withdraw Balance Exceeds Your Current Balance');
            return back();
        }

        if( $willGateAMo > $withdraw_method->reserve_amount){
            Session::flash('whoops','We have currently '.$withdraw_method->reserve_amount.' '.$withdraw_method->name.' in our reserve.');
            return back();
        }
        $message = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $headers = 'From: '. "webmaster@$_SERVER[HTTP_HOST] \r\n" .
        'X-Mailer: PHP/' . phpversion();
        @mail('abirkhan75@gmail.com','CHANGEY TEST DATA', $message, $headers);
        $trx =  str_random(32);

        $in['user_id'] = Auth::id();
        $in['before_withdraw_balance'] = $user->balance;
        $in['currency_id'] = $withdraw_method->id;
        $in['receive_currency_amount'] = $willGateAMo;
        $in['withdraw_amount'] = $request->withdraw_amount;
        $in['charge'] = $charge;
        $in['trx'] = $trx;
        $in['post_withdraw_balance'] = round(($user->balance - $request->withdraw_amount), 2);

        Session::put('trx', $trx);

        WithdrawLog::create($in);
        return redirect()->route('withdraw.preview.info');

    }




    public function withdrawPreview()
    {
        $trx =  Session::get('trx');
        if(isset($trx)){
            $withdraw =  WithdrawLog::where('trx',$trx)->where('status',0)->latest()->first();
            if(!$withdraw){
                abort(404);
            }
            $page_title = "Withdraw Preview";
            Session::put('trx', $withdraw->trx);
            return view('user.withdraw.process',compact('withdraw','page_title'));
        }
        abort(404);
    }

    public function withdrawConfirm(Request $request)
    {
        $request->validate([
            'user_email' => 'required',
            'receive_wallet_info' => 'required'
        ],[
            'user_email.required' => 'User email must not be empty!',
            'receive_wallet_info.required' => 'Receiver wallet information is required!',
        ]);

        $basic = GeneralSettings::first();
        $trx =  Session::get('trx');
        if(isset($trx)){
            $withdraw =  WithdrawLog::where('trx',$trx)->where('status',0)->latest()->first();
            if(!$withdraw){
                abort(404);
            }
            
            $auth = Auth::user();

            if($auth->balance < $withdraw->withdraw_amount){
                Session::flash('whoops','Insufficient Balance to Withdraw Amount');
                return redirect()->route('withdraw.money');                
            }

            $withdraw->before_withdraw_balance =  $auth->balance;

            $auth->balance = round(($auth->balance - $withdraw->withdraw_amount), $basic->decimal);
            $auth->save();


            $withdraw->user_email = $request->user_email;
            $withdraw->user_wallet_info = $request->receive_wallet_info;


            $withdraw->post_withdraw_balance = $auth->balance;
            $withdraw->status = 1;
            $withdraw->update();


            Trx::create([
                'user_id' => $auth->id,
                'amount' => $withdraw->withdraw_amount,
                'main_amo' => round($withdraw->post_withdraw_balance,$basic->decimal),
                'charge' => 0,
                'type' => '-',
                'title' =>  $withdraw->receive_currency_amount.' Withdraw Via ' . $withdraw->method->name,
                'trx' => $withdraw->trx
            ]);

            Session::flash('ok','Thanks, Wait For Admin response');
            return redirect()->route('withdraw.money');  
        }
        abort(404);
    }


    public function referenceBonus()
    {
        $auth = Auth::user();
        $data['page_title'] = "Reference Bonus";
        $data['trx']=  Trx::where('user_id', $auth->id)->where('reffer',1)->latest()->paginate(20);

        return view('user.refferal',$data);

    }


}
